<cfcomponent extends="xmlrpc" output="false">
	<!--- 
		Author: Roger Benningfield
		This CFC may be used without fee or warranty, but may not be
		redistributed in any fashion. Documentation is available
		via Macromedia in the Developers Resource Kit Volume 4.
	--->
	<cffunction name="xmlrpc" access="remote" returntype="string">
		<cfargument name="paramNames" required="false" default="" type="string" hint="A pipe-delimited list of names for the top level params contained in the body of an XML-RPC request." />
		<cfset var myRpcPayload = GetHttpRequestData().content />
		<cfset var myRpc = XmlRpc2Cfml(myRpcPayload) />
		<cfset var myResult = "" />
		<cfset var myRpcResult = ArrayNew(1) />
		<cfset var myParamName = "" />
		<cfset var i = 0 />
		<cftry>
			<cfcontent type="text/xml" />
			<!--- VERIFY THAT THE REQUESTED METHOD EXISTS AND IS EXPOSED VIA XML-RPC --->
			<cfif StructKeyExists(this, myRpc.method) AND StructKeyExists(GetMetaData(this[myRpc.method]), "xmlRpcAccess") AND GetMetaData(this[myRpc.method]).xmlRpcAccess>
				<!--- INVOKE THE DESIRED METHOD, LOOPING OVER THE INCOMING PARAMS AND
				NAMING THEM WHEN POSSIBLE --->
				<cfinvoke method="#myRpc.method#" returnvariable="myResult">
					<cfloop index="i" from="1" to="#ArrayLen(myRpc.params)#">
						<cfif ListLen(arguments.paramNames, "|") GTE i>
							<cfset myParamName = ListGetAt(arguments.paramNames, i, "|") />
						<cfelse>
							<cfset myParamName = "param#i#" />
						</cfif>
						<cfinvokeargument name="#myParamName#" value="#myRpc.params[i]#" />
					</cfloop>
				</cfinvoke>
				<!--- PLACE THE RESULT IN AN ARRAY AND CALL XMLRPC.CFC'S SERIALIZER --->
				<cfset myRpcResult[1] = myResult />
				<cfset myResult = "<?xml version=""1.0"" encoding=""iso-8859-1""?>" & Cfml2XmlRpc(myRpcResult, "response") />
				<!--- SOME XML-RPC IMPLEMENTATIONS WILL FAIL WHEN THE CONTENT-LENGTH
				DOES NOT MATCH THE CONTENT PRECISELY. CLEARBUFFER() PREVENTS SUCH
				ERRORS. --->
				<cfheader name="Content-Length" value="#Len(myResult)#" />
				<cfscript>
					getPageContext().getOut().clearBuffer();
					writeOutput(myResult);</cfscript><cfabort />
			<cfelse>
				<cfthrow type="method" message="The requested method does not exist." />
			</cfif>
			<cfcatch type="any">
				<!--- SERIALIZE ANY ERROR MESSAGES AND RETURN THEM TO THE CLIENT --->
				<cfset myRpcResult[1] = 0 />
				<cfset myRpcResult[2] = cfcatch.message />
				<cfset myResult = "<?xml version=""1.0"" encoding=""iso-8859-1""?>" & Cfml2XmlRpc(myRpcResult, "responsefault") />
				<cfheader name="Content-Length" value="#Len(myResult)#" />
				<cfscript>
					getPageContext().getOut().clearBuffer();
					writeOutput(myResult);</cfscript><cfabort />
			</cfcatch>
		</cftry>	
	</cffunction>
</cfcomponent>